﻿using B.S.BasicData.API.Read.Application.Command.Leave;
using B.S.BasicData.API.Read.DTOS.Leave;
using B.S.BasicData.Domain.Entities.Leave;
using B.S.BasicData.ErrorCode;
using B.S.BasicData.Infrastructure.Interface;
using MediatR;

namespace B.S.BasicData.API.Read.Application.Handler.Leave
{
    /// <summary>
    /// 获取员工请假报表数据请求命令处理类
    /// </summary>
    public class GetLeaveReportHandler:IRequestHandler<GetLeaveReportCommand,ApiResult<LeaveReportDTO>>
    {
        IBaseRepository<LeaveApplicationModel> leaveRep;

        public GetLeaveReportHandler(IBaseRepository<LeaveApplicationModel> leaveRep)
        {
            this.leaveRep = leaveRep;
        }

        public Task<ApiResult<LeaveReportDTO>> Handle(GetLeaveReportCommand request, CancellationToken cancellationToken)
        {
            try
            {
                ApiResult<LeaveReportDTO> res = new ApiResult<LeaveReportDTO>();
                var query = leaveRep.GetAll().Where(c => !c.IsDeleted&&c.State==LeaveStateEnum.已通过).Select(x => new
                {
                    x.ApplicationName,
                    x.StartTime,
                    x.EndTime,
                    x.TotalTime,
                }).ToList();


                if(!string.IsNullOrEmpty(request.leavename))
                {
                    query = query.Where(x => x.ApplicationName.Contains(request.leavename)).ToList();
                }

                var result = new Dictionary<string, int[]>();

                foreach (var item in query)
                {
                    if (!result.ContainsKey(item.ApplicationName))
                    {
                        result[item.ApplicationName] = new int[12];
                    }
                    var currentDate = item.StartTime;
                    var endDate = item.EndTime;
                    var workStartTime = 9; // 工作开始时间（小时）
                    var workEndTime = 17;  // 工作结束时间（小时）

                    while (currentDate <= endDate)
                    {
                        var monthIndex = currentDate.Month - 1;
                        var dailyHours = 0;

                        // 计算当天的工作时间段
                        var dayWorkStart = new DateTime(
                            currentDate.Year,
                            currentDate.Month,
                            currentDate.Day,
                            workStartTime, 0, 0
                        );
                        var dayWorkEnd = new DateTime(
                            currentDate.Year,
                            currentDate.Month,
                            currentDate.Day,
                            workEndTime, 0, 0
                        );

                        // 计算当天实际请假时间段
                        var actualStart = currentDate == item.StartTime.Date
                            ? (item.StartTime > dayWorkStart ? item.StartTime : dayWorkStart)
                            : dayWorkStart;

                        var actualEnd = currentDate == item.EndTime.Date
                            ? (item.EndTime < dayWorkEnd ? item.EndTime : dayWorkEnd)
                            : dayWorkEnd;

                        // 计算当天的请假工时
                        if (currentDate.Date == item.StartTime.Date)
                        {
                            // 开始日期：计算StartTime到当天工作结束时间(17:00)的请假工时
                            var start = item.StartTime;
                            var end = dayWorkEnd;
                            if (start < end)
                            {
                                dailyHours = Math.Min(8, (int)(end - start).TotalHours);
                            }
                        }
                        else if (currentDate.Date == endDate.Date)
                        {
                            // 结束日期：计算当天工作开始时间(9:00)到EndTime的请假工时
                            var start = dayWorkStart;
                            var end = item.EndTime;
                            if (start < end)
                            {
                                dailyHours = Math.Min(8, (int)(end - start).TotalHours);
                            }
                        }
                        else
                        {
                            // 中间日期：如果有全天请假，计算8小时
                            dailyHours = 8;
                        }

                        result[item.ApplicationName][monthIndex] += dailyHours;
                        currentDate=currentDate.AddDays(1);
                        currentDate = new DateTime(currentDate.Year, currentDate.Month, currentDate.Day, 0, 0, 0);
                    }
                }

                var dto = new LeaveReportDTO
                {
                    LeaveApplicationList = result,
                };

                res.Msg = "成功";
                res.Code = ApiEnum.Success;
                res.Data = dto;
                return Task.FromResult(res);
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}
